<script lang="ts">
  import { _ } from 'svelte-i18n';

  import { assertExhaustive } from '@mathesar/component-library';
  import Button from '@mathesar/component-library/button/Button.svelte';
  import Tooltip from '@mathesar/component-library/tooltip/Tooltip.svelte';
  import ContentLoading from '@mathesar/components/ContentLoading.svelte';
  import { toast } from '@mathesar/stores/toast';

  import { getFileViewerType } from '../fileUtils';

  import FileIcon from './FileIcon.svelte';
  import type { FileViewerController } from './FileViewerController';

  export let fileViewerController: FileViewerController;

  $: ({ manifest, canOpenViewer } = fileViewerController);

  /**
   * This controls the pixel dimensions of the fetched thumbnail size, as
   * generated by the service layer. It does not control the visual size of the
   * thumbnail.
   */
  export let thumbnailResolutionHeightPx: number;

  let thumbnailElement: HTMLImageElement;
  let defaultFileTrigger: HTMLElement;

  $: ({ uri, thumbnail, mimetype } = manifest);
  $: fileViewerType = getFileViewerType(manifest);
  $: thumbnailUrl = `${thumbnail}?height=${thumbnailResolutionHeightPx}`;
  $: fileName = manifest.name;

  $: fileViewerController.setTriggerRetriever(() =>
    fileViewerType === 'image' ? thumbnailElement : defaultFileTrigger,
  );
  $: ({ isLoading } = fileViewerController);

  async function openViewer() {
    try {
      await fileViewerController.openFileViewer();
    } catch (err) {
      console.error(err);
      toast.error($_('failed_to_load_image'));
    }
  }
</script>

<div class="file-cell-content">
  <div class="attached-file" class:can-open={$canOpenViewer}>
    {#if fileViewerType === 'image'}
      <ContentLoading loading={$isLoading}>
        <Tooltip>
          <svelte:fragment slot="content">{fileName}</svelte:fragment>
          <div slot="trigger" class="image">
            <img
              alt={uri}
              src={thumbnailUrl}
              on:click={openViewer}
              bind:this={thumbnailElement}
            />
          </div>
        </Tooltip>
      </ContentLoading>
    {:else if fileViewerType === 'default'}
      <Button
        on:click={openViewer}
        bind:element={defaultFileTrigger}
        aria-label={uri}
        tooltip={fileName}
        appearance="secondary"
      >
        <FileIcon {mimetype} />
      </Button>
    {:else}
      {assertExhaustive(fileViewerType)}
    {/if}
  </div>
</div>

<style lang="scss">
  .file-cell-content {
    display: grid;
    overflow: hidden;
    height: 100%;
    --ContentLoading__height: 100%;
  }

  .attached-file {
    height: 100%;
    overflow: hidden;
    display: flex;
    padding: 0.1em;
  }

  .image {
    height: 100%;
    width: fit-content;
    cursor: pointer;

    img {
      display: block;
      height: 100%;
      border: solid 1px var(--color-border-input);
      border-radius: var(--border-radius-m);
    }
  }

  .attached-file.can-open .image {
    cursor: pointer;
  }
</style>
